/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include <向量.h>
#include "四元数.h"



static mat3X3 g单位矩阵3X3 = { {1,0,0},{0,1,0},{0,0,1} };


Inline mat2 f_mat2_angle(const float32 角度) {
	mat2 mat;
	mat.m0 = { cos(角度), -sin(角度) };
	mat.m1 = { sin(角度), cos(角度) };
	return mat;
}

CUDA_CALLABLE inline mat3X3 f_mat3x3_quat(const vec4& quat) {
	mat3X3 mat;
	mat.row0 = f_quat_Rotate(quat, { 1,0,0 });
	mat.row1 = f_quat_Rotate(quat, { 0,1,0 });
	mat.row2 = f_quat_Rotate(quat, { 0,0,1 });
	return mat;
}

CUDA_CALLABLE inline Mat44f f_mat4x4_quat(const vec4& quat) {
	Mat44f mat; vec3 a;
	a = f_quat_Rotate(quat, { 1,0,0 });
	mat.m00 = a.x; mat.m01 = a.y; mat.m02 = a.z; mat.m03 = 0;
	a = f_quat_Rotate(quat, { 0,1,0 });
	mat.m10 = a.x; mat.m11 = a.y; mat.m12 = a.z; mat.m13 = 0;
	a = f_quat_Rotate(quat, { 0,0,1 });
	mat.m20 = a.x; mat.m21 = a.y; mat.m22 = a.z; mat.m23 = 0;

	mat.m30 = a.x; mat.m31 = a.y; mat.m32 = a.z; mat.m33 = 1;
	return mat;
}


inline void mat33_normalize(mat3X3& mat) {
	vec3* p = (vec3*)&mat;
	for (int i = 0; i < 3; ++i) {
		vec_normalize(&p[i]);
	}
}


Inline mat3X3 f_mat3x3_T(const mat3X3& mat) {
	mat3X3 rm;
	rm.row0.x = mat.row0.x;
	rm.row1.x = mat.row0.y;
	rm.row2.x = mat.row0.z;

	rm.row0.y = mat.row1.x;
	rm.row1.y = mat.row1.y;
	rm.row2.y = mat.row1.z;

	rm.row0.z = mat.row2.x;
	rm.row1.z = mat.row2.y;
	rm.row2.z = mat.row2.z;

	return rm;
}


CUDA_CALLABLE inline C_Mat44 f_mat3x3_4X4(mat3X3 mat33) {
	C_Mat44 mat = C_Mat44::kIdentity;
	mat.columns[0][0] = mat33.row0.x;
	mat.columns[0][1] = mat33.row0.y;
	mat.columns[0][2] = mat33.row0.z;
	
	mat.columns[1][0] = mat33.row1.x;
	mat.columns[1][1] = mat33.row1.y;
	mat.columns[1][2] = mat33.row1.z;

	mat.columns[2][0] = mat33.row2.x;
	mat.columns[2][1] = mat33.row2.y;
	mat.columns[2][2] = mat33.row2.z;
	return mat;
}

Inline void f_mat_multiply(float32* r, float32* lhs, float32* rhs, uvec2 lm, uvec2 rm) {
	for (int i=0; i < lm.x; ++i) {
		for (int j=0; j < rm.y; ++j) {
			float32 和 = 0.0f;

			for (int k=0; k < lm.x; ++k) {
				和 += lhs[k*lm.y + i] * rhs[j * rm.y + k];
			}

			r[j * rm.y + i] = 和;
		}
	}
}

CUDA_CALLABLE inline mat3X3 f_mat44_to_33(const Mat44f& 矩阵, bool 归一化 = false) {
	mat3X3 mat;
	mat.row0 = { 矩阵.m00, 矩阵.m01, 矩阵.m02 };
	mat.row1 = { 矩阵.m10, 矩阵.m11, 矩阵.m12 };
	mat.row2 = { 矩阵.m20, 矩阵.m21, 矩阵.m22 };
	/*Mat44f material = 矩阵;
	material.m30 = 0;
	material.m31 = 0;
	material.m32 = 0;
	material.m33 = 1;
	auto identity = f_mat44_identity();
	mat4X3 m1 = f_mat43_identity();
	mat4X3 mr = f_mat43_identity();
	mat3X4 m34 = f_mat34_identity(); 
	
	f_mat_multiply((float32*)&mr, (float32*)&material, (float32*)&m1, {4,4}, {4,3});
	f_mat_multiply((float32*)&mat, (float32*)&m34, (float32*)&mr, {3,4}, {4,3});*/
	
	if(归一化) mat33_normalize(mat);
	return (mat);
}


Inline Mat44f f_mat33_to_44(const mat3X3& 矩阵) {
	Mat44f mat;
	mat.m00 = 矩阵.row0.x; mat.m01 = 矩阵.row0.y; mat.m02 = 矩阵.row0.z; mat.m03 = 0;
	mat.m10 = 矩阵.row1.x; mat.m11 = 矩阵.row1.y; mat.m12 = 矩阵.row1.z; mat.m13 = 0;
	mat.m20 = 矩阵.row2.x; mat.m21 = 矩阵.row2.y; mat.m22 = 矩阵.row2.z; mat.m23 = 0;
	mat.m30 = 0; mat.m31 = 0; mat.m32 = 0; mat.m33 = 1;
	return mat;
}




CUDA_CALLABLE inline vec4 mat3x3_to_quat(const mat3X3& m) {
	//Mat变换坐标3()
	vec4 q;
	float32 tr = m.row0.x + m.row1.y + m.row2.z, h;

	if (tr >= 0) {
		h = sqrtf(tr + 1);
		q.w = 0.5f * h;
		h = 0.5f / h;

		q.x = (m.row2.y - m.row1.y) * h;
		q.y = (m.row0.z - m.row2.x) * h;
		q.z = (m.row1.x - m.row0.y) * h;
	}
	else
	{
		uint32 i = 0;
		float32* p_m = ((float32*)&m);
		if (m.row1.y > m.row0.x)
			i = 1;
		if (m.row2.z > p_m[i*3 + i])
			i = 2;

		switch (i) {
		case 0:
			h = sqrtf((m.row0.x - (m.row1.y + m.row2.z)) + 1);
			q.x = 0.5f * h;
			h = 0.5f / h;

			q.y = (m.row0.y + m.row1.x) * h;
			q.z = (m.row2.x + m.row0.z) * h;
			q.w = (m.row2.y - m.row1.z) * h;
			break;
		case 1:
			h = sqrtf((m.row1.y - (m.row2.z + m.row0.x)) + 1);
			q.y = 0.5f * h;
			h = 0.5f / h;

			q.z = (m.row1.z + m.row2.y) * h;
			q.x = (m.row0.y + m.row1.x) * h;
			q.w = (m.row0.z - m.row2.x) * h;
			break;
		case 2:
			h = sqrtf((m.row2.z - (m.row0.x + m.row1.y)) + 1);
			q.z = 0.5f * h;
			h = 0.5f / h;

			q.x = (m.row2.x + m.row0.z) * h;
			q.y = (m.row1.z + m.row2.y) * h;
			q.w = (m.row1.x - m.row0.y) * h;
			break;
		default: // Make compiler happy
			q.x = q.y = q.z = q.w = 0;
			break;
		}
	}
	return q;
}



CUDA_CALLABLE Inline mat3X3 f_mat3x3_从轴向构建旋转矩阵(float32 角度, const vec3& 轴) {
	float32 弧度 = M_角度转弧度(角度);

	vec3 a = vec_normalize2(轴);
	float32 s = sinf(弧度);
	float32 c = cosf(弧度);

	mat3X3 rm = g单位矩阵3X3;

	rm.row0.x = a.x * a.x + (1.0f - a.x * a.x) * c;
	rm.row0.y = a.x * a.y * (1.0f - c) + a.z * s;
	rm.row0.z = a.x * a.z * (1.0f - c) - a.y * s;

	rm.row1.x = a.x * a.y * (1.0f - c) - a.z * s;
	rm.row1.y = a.y * a.y + (1.0f - a.y * a.y) * c;
	rm.row1.z = a.y * a.z * (1.0f - c) + a.x * s;
	
	rm.row2.x = a.x * a.z * (1.0f - c) + a.y * s;
	rm.row2.y = a.y * a.z * (1.0f - c) - a.x * s;
	rm.row2.z = a.z * a.z + (1.0f - a.z * a.z) * c;
	
	return rm;
}

CUDA_CALLABLE Inline mat3X3 f_mat3x3_Multiply(const mat3X3& ma, const mat3X3& mb) {
	mat3X3 rm;

	const float32* l = (float32*)&ma;
	const float32* r = (float32*)&ma;
	for (int i=0; i < 3; ++i) {
		for (int j=0; j < 3; ++j) {
			((float32*)&rm)[j * 3 + i] = r[j * 3 + 0] * l[i + 0];
			((float32*)&rm)[j*3+i] += r[j*3+1]*l[i+3];
			((float32*)&rm)[j*3+i] += r[j*3+2]*l[i+6];
		}
	}

	return rm;
}

Inline vec3 operator * (const mat3X3& mat, const vec3& v) {
	vec3 r;
	r.x = v.x * mat.row0.x + v.y * mat.row1.x + v.z * mat.row2.x;
	r.y = v.x * mat.row0.y + v.y * mat.row1.y + v.z * mat.row2.y;
	r.z = v.x * mat.row0.z + v.y * mat.row1.z + v.z * mat.row2.z;
	return r;
}

Inline vec2 operator * (const mat2& mat, const vec2& v) {
	vec2 r;
	r.x = v.x * mat.m0.x + v.y * mat.m1.x ;
	r.y = v.x * mat.m0.y + v.y * mat.m1.y ;
	return r;
}

Inline void operator *= (vec3& v, const mat3X3& mat) {
	vec3 r = v;
	r.x = v.x * mat.row0.x + v.y * mat.row1.x + v.z * mat.row2.x;
	r.y = v.x * mat.row0.y + v.y * mat.row1.y + v.z * mat.row2.y;
	r.z = v.x * mat.row0.z + v.y * mat.row1.z + v.z * mat.row2.z;
	v = r;
}



CUDA_CALLABLE inline mat3X3 f_mat3x3_从全局旋转角构建矩阵(const vec3& rot) {
	mat3X3 rm = g单位矩阵3X3;

	auto rx = f_mat3x3_从轴向构建旋转矩阵(rot.x, { 1.0f,0.0f,0.0f });
	auto ry = f_mat3x3_从轴向构建旋转矩阵(rot.y, { 0.0f,1.0f,0.0f });
	auto rz = f_mat3x3_从轴向构建旋转矩阵(rot.z, { 0.0f,0.0f,1.0f });

	//rm = rm * rz;
	rm = f_mat3x3_Multiply(rm, rz);
	rm = f_mat3x3_Multiply(rm, ry);
	rm = f_mat3x3_Multiply(rm, rx);

	return rm;
}



Inline vec3 f_graph_旋转矩阵转欧拉角(const mat3X3& mat) {
	//assert(isRotationMatirx(R));
	double sy = sqrt(mat.row0.x * mat.row0.x + mat.row1.x * mat.row1.x);
	bool singular = sy < 1e-6;
	vec3  xyz;
	if (!singular) {
		xyz.x = M_弧度转角度(atan2(mat.row2.y, mat.row2.z));
		xyz.y = M_弧度转角度(atan2(-mat.row2.x, sy));
		xyz.z = M_弧度转角度(atan2(mat.row1.x, mat.row0.x));
	}
	else {
		xyz.x = M_弧度转角度(atan2(-mat.row1.z, mat.row1.y));
		xyz.y = M_弧度转角度(atan2(-mat.row2.x, sy));
		xyz.z = 0;
	}
	return xyz;
	/*double sy = sqrt(R(0, 0) * R(0, 0) + R(1, 0) * R(1, 0));
	bool singular = sy < 1e-6;
	double x, y, z;
	if (!singular)
	{
		x = atan2(R(2, 1), R(2, 2));
		y = atan2(-R(2, 0), sy);
		z = atan2(R(1, 0), R(0, 0));
	}
	else
	{
		x = atan2(-R(1, 2), R(1, 1));
		y = atan2(-R(2, 0), sy);
		z = 0;
	}
	return { x, y, z };*/
}


CUDA_CALLABLE inline void f_normalize(mat3X3& mat) {
	vec_normalize(&mat.row0);
	vec_normalize(&mat.row1);
	vec_normalize(&mat.row2);
}


CUDA_CALLABLE inline mat3X3 f_mat_multi(const mat3X3& matA, const mat3X3& matB) {
	mat3X3 结果矩阵 = {};
	for (uint8 i = 0; i < 3; ++i) {
		for (uint8 y = 0; y < 3; ++y) {
			for (uint8 x = 0; x < 3; ++x) {
				((float32*)&结果矩阵)[i * 3 + y] += ((const float32*)&matA)[x * 3 + i] + ((const float32*)&matB)[y * 3 + x];
			}
		}
	}
}







CUDA_CALLABLE inline Mat44f f_mat44_构建移动矩阵(const vec3& s) {
	Mat44f m = f_mat44_identity();
	m.m30 = s.x;
	m.m31 = s.y;
	m.m32 = s.z;
	return m;
}

CUDA_CALLABLE inline Mat44f f_mat44_构建行式旋转矩阵(const vec3& a, float32 angle) {
	Mat44f m;

	angle = M_角度转弧度(angle);
	//angle = (angle);
	vec3 axis = vec_normalize2(a);
	float s = sinf(angle);
	float c = cosf(angle);


	m.m00 = a.x * a.x + (1.0f - a.x * a.x) * c;
	m.m01 = a.x * a.y * (1.0f - c) + a.z * s;
	m.m02 = a.x * a.z * (1.0f - c) - a.y * s;
	m.m03 = 0.0f;

	m.m10 = a.x * a.y * (1.0f - c) - a.z * s;
	m.m11 = a.y * a.y + (1.0f - a.y * a.y) * c;
	m.m12 = a.y * a.z * (1.0f - c) + a.x * s;
	m.m13 = 0.0f;

	m.m20 = a.x * a.z * (1.0f - c) + a.y * s;
	m.m21 = a.y * a.z * (1.0f - c) - a.x * s;
	m.m22 = a.z * a.z + (1.0f - a.z * a.z) * c;
	m.m23 = 0.0f;

	m.m30 = 0.0f;
	m.m31 = 0.0f;
	m.m32 = 0.0f;
	m.m33 = 1.0f;

	return m;
}

Inline Mat44f f_mat44_构建X旋转矩阵(float32 a) {
	Mat44f m = f_mat44_identity();
	a = M_角度转弧度(a);
	
	m.m11 = (float32)cos(a);
	m.m12 = (float32)sin(a);
	m.m21 = (float32)-sin(a);
	m.m22 = (float32)cos(a);
	
	return m;
}

Inline Mat44f f_mat44_构建Y旋转矩阵(float32 a) {
	Mat44f m = f_mat44_identity();
	a = M_角度转弧度(a);
	
	m.m00 = (float32)cos(a);
	m.m02 = (float32)-sin(a);
	m.m20 = (float32)sin(a);
	m.m22 = (float32)cos(a);
	
	return m;
}

Inline Mat44f f_mat44_构建Z旋转矩阵(float32 a) {
	Mat44f m = f_mat44_identity();
	a = M_角度转弧度(a);

	m.m00 = (float32)cos(a);
	m.m01 = (float32)sin(a);
	m.m10 = (float32)-sin(a);
	m.m11 = (float32)cos(a);

	return m;
}


CUDA_CALLABLE inline Mat44f f_mat44_构建缩放矩阵(const vec3& s) {
	auto m = f_mat44_identity();

	m.m00 = s.x;
	m.m11 = s.y;
	m.m22 = s.z;

	return m;
}

Inline Mat44f f_mat44_Inverse(const Mat44f& mat) {
	Mat44f invm;
	float32* mp = (float32*)&invm;
	const float32* mat_p = (const float32*)&mat;
	for (int c = 0; c < 4; ++c) {
		for (int r = 0; r < 4; ++r) {
			mp[c*4 + r] = mat_p[r*4+c];
		}
	}

	mp[12 + 0] = -vec_dot(&mat_p[12], &mat_p[0]);
	mp[12 + 1] = -vec_dot(&mat_p[12], &mat_p[4]);
	mp[12 + 2] = -vec_dot(&mat_p[12], &mat_p[8]);
	mp[12 + 3] = 1.0f;

	return invm;
}

Inline Mat44f f_mat44_T(const Mat44f& mat) {
	Mat44f matT;
	matT.m00 = mat.m00;
	matT.m10 = mat.m01;
	matT.m20 = mat.m02;
	matT.m30 = mat.m03;

	matT.m01 = mat.m10;
	matT.m11 = mat.m11;
	matT.m21 = mat.m12;
	matT.m31 = mat.m13;

	matT.m02 = mat.m20;
	matT.m12 = mat.m21;
	matT.m22 = mat.m22;
	matT.m32 = mat.m23;

	matT.m03 = mat.m30;
	matT.m13 = mat.m31;
	matT.m23 = mat.m32;
	matT.m33 = mat.m33;

	return matT;
}

CUDA_CALLABLE inline void mat44_normalize(Mat44f& mat) {
	vec4* p = (vec4*)&mat;
	for (int i = 0; i < 4; ++i) {
		vec_normalize(&p[i]);
	}
}

CUDA_CALLABLE inline Mat44f f_mat44_构建欧拉角旋转矩阵(const vec3& a) {
	Mat44f m = f_mat44_identity();

	vec3 弧度 = vec3_角度转弧度(a);


	/*m.m00 = cos(弧度.y) * cos(弧度.z);
	m.m01 = -sin(弧度.y);
	m.m02 = cos(弧度.y) * sin(弧度.z);

	m.m10 = cos(弧度.z) * sin(弧度.x) * sin(弧度.y) - cos(弧度.x) * sin(弧度.z);
	m.m11 = cos(弧度.x) * cos(弧度.z) + sin(弧度.x) * sin(弧度.y) * sin(弧度.z);
	m.m12 = cos(弧度.x) * cos(弧度.y);

	m.m20 = cos(弧度.x) * sin(弧度.y) + cos(弧度.z) * sin(弧度.x) * sin(弧度.z);
	m.m21 = cos(弧度.x) * sin(弧度.y) * sin(弧度.z) - sin(弧度.x) * cos(弧度.z);
	m.m22 = cos(弧度.x) * cos(弧度.y);*/

	m.m00 = cos(弧度.y) * cos(弧度.z);
	m.m01 = cos(弧度.z) * sin(弧度.x) * sin(弧度.y) - cos(弧度.x) * sin(弧度.z);
	m.m02 = sin(弧度.x) * sin(弧度.z) + cos(弧度.x) * cos(弧度.z) * sin(弧度.y);

	m.m10 = cos(弧度.y) * sin(弧度.z);
	m.m11 = cos(弧度.x) * cos(弧度.z) + sin(弧度.x) * sin(弧度.y) * sin(弧度.z);
	m.m12 = cos(弧度.x) * sin(弧度.y) * sin(弧度.z) - cos(弧度.z) * sin(弧度.z);

	m.m20 = -sin(弧度.y);
	m.m21 = cos(弧度.y) * sin(弧度.x);
	m.m22= cos(弧度.x) * cos(弧度.y);

	/*m.m00 = cos(弧度.y) * cos(弧度.z);
	m.m10 = cos(弧度.z) * sin(弧度.x) * sin(弧度.y) - cos(弧度.x) * sin(弧度.z);
	m.m20 = sin(弧度.x) * sin(弧度.z) + cos(弧度.x) * cos(弧度.z) * sin(弧度.y);

	m.m01 = cos(弧度.y) * sin(弧度.z);
	m.m11 = cos(弧度.x) * cos(弧度.z) + sin(弧度.x) * sin(弧度.y) * sin(弧度.z);
	m.m21 = cos(弧度.x) * sin(弧度.y) * sin(弧度.z) - cos(弧度.z) * sin(弧度.z);

	m.m02 = -sin(弧度.y);
	m.m12 = cos(弧度.y) * sin(弧度.x);
	m.m22 = cos(弧度.x) * cos(弧度.y);*/

	return m;
}


Inline Mat44f f_mat44_构建XYZ旋转矩阵(const S_Tranform& t) {
	Mat44f mat = f_mat44_identity();
	//auto rx = f_mat44_构建行式旋转矩阵(t.rotation.x, { 1.0f,0.0f,0.0f });
	//auto ry = f_mat44_构建行式旋转矩阵(t.rotation.y, { 0.0f,1.0f,0.0f });
	//auto rz = f_mat44_构建行式旋转矩阵(t.rotation.z, { 0.0f,0.0f,1.0f });
	auto rx = f_mat44_构建X旋转矩阵(t.rotation.x);
	auto ry = f_mat44_构建Y旋转矩阵(t.rotation.y);
	auto rz = f_mat44_构建Z旋转矩阵(t.rotation.z);
	//return (rx * ry * rz);
	//mat *= rz;
	//mat *= ry;
	//mat *= rx;
	return (rz * ry * rx);

	const float s1 = Sin(M_角度转弧度(t.rotation.z));
	const float c1 = Cos(M_角度转弧度(t.rotation.z));
	const float s2 = Sin(M_角度转弧度(t.rotation.x));
	const float c2 = Cos(M_角度转弧度(t.rotation.x));
	const float s3 = Sin(M_角度转弧度(t.rotation.y));
	const float c3 = Cos(M_角度转弧度(t.rotation.y));

	// interprets the angles as yaw around world-y, pitch around new z, roll around new x
	float mr[4][4] = { { c2 * c3, s2, -c2 * s3, 0.0f},
						{ s1 * s3 - c1 * c3 * s2, c1 * c2, c3 * s1 + c1 * s2 * s3, 0.0f},
						{ c3 * s1 * s2 + c1 * s3, -c2 * s1, c1 * c3 - s1 * s2 * s3, 0.0f},
						{ t.location.x, t.location.y, t.location.z, 1.0f} };

	mat = *((Mat44f*)mr);
	return mat;
	
	
	//return (f_mat44_构建欧拉角旋转矩阵({}) * rz * ry * rx);
}

Inline Mat44f f_mat44_构建XYZ欧拉旋转矩阵(const S_Tranform& t) {
	Mat44f mat = f_mat44_identity();

	auto rx = f_mat44_构建行式旋转矩阵({ 1.0f,0.0f,0.0f }, t.rotation.x);
	auto ry = f_mat44_构建行式旋转矩阵({ 0.0f,1.0f,0.0f }, t.rotation.y);
	auto rz = f_mat44_构建行式旋转矩阵({ 0.0f,0.0f,1.0f }, t.rotation.z);

	mat *= rx * ry * rz;
	//mat *= rz * ry * rx;
	return mat;
}


Inline Mat44f f_mat44_构建XYZ变换矩阵(const S_Tranform& t) {
	Mat44f mat;

	auto s = f_mat4_构建缩放矩阵(t.scale);
	//return f_mat44_构建XYZ旋转矩阵(t) * s;
	//mat = f_mat44_构建移动矩阵(t.location) * f_mat44_构建XYZ欧拉旋转矩阵(t);
	//mat = f_mat44_构建移动矩阵(t.location) * f_mat44_构建欧拉角旋转矩阵(t.rotation);
	mat = f_mat44_构建移动矩阵(t.location) * f_mat44_构建XYZ旋转矩阵(t);
	
	mat *= s;

	return mat;
}


Inline Mat44f f_mat44_构建(const mat3X3& rot, const vec3& pos) {
	Mat44f mat = f_mat44_identity();

	for (uint8 i = 0; i < 3; ++i) {
		for (uint8 j = 0; j < 3; ++j) {
			((float32*)&mat)[i * 4 + j] = ((float32*)&rot)[i * 3 + j];
		}
	}
	
	mat.m30 = pos.x;
	mat.m31 = pos.y;
	mat.m32 = pos.z;

	return mat;
}


inline Mat44f f_mat44_LookAtMatrix(const vec3& 眼睛位置, const vec3& target, const vec3& up) {
	vec3 forward = vec_normalize(target - 眼睛位置);
	//forward.x = -forward.x;
	//forward.y = -forward.y;
	//forward.z = -forward.z;
	//Vec3 up(0.0f, 1.0f, 0.0f);
	vec3 left = vec_normalize(vec_cross(up, forward));
	vec3 Up = vec_normalize(vec_cross(forward, left));

	/*float xform[4][4] = {{left.x, left.y, left.z, 0.0f},
						{ Up.x, -Up.y, Up.z, 0.0f},
						{ forward.x, forward.y, forward.z, 0.0f},
						{ viewer.x, viewer.y, viewer.z, 1.0f}
	};*/

	/*Mat44f mat = {
		left.x, left.y, left.z, 0.0f,
		Up.x, -Up.y, Up.z, 0.0f,
		forward.x, forward.y, forward.z, 0.0f,
		眼睛位置.x, 眼睛位置.y, 眼睛位置.z, 1.0f
	};*/


	//forward.x = -forward.x;
	//forward.y = -forward.y;
	//forward.z = -forward.z;
	Mat44f mat = {
		left.x, left.y, left.z, 0.0f,
		Up.x, Up.y, Up.z, 0.0f,
		forward.x, forward.y, forward.z, 0.0f,
		0, 0, 0, 1.0f
		//眼睛位置.x, 眼睛位置.y, 眼睛位置.z, 1.0f
	};

	return mat;
	//return AffineInverse(Mat44(&xform[0][0]));
}


Inline mat3X4 f_mat3x4_转换(const Mat44f& t) {
	mat3X4 mat;
	mat.row0 = { t.m00, t.m10, t.m20, t.m30 };
	mat.row1 = { t.m01, t.m11, t.m21, t.m31 };
	mat.row2 = { t.m02, t.m12, t.m22, t.m32 };
	return mat;
}


/*Inline mat3X3 f_mat44_to_33Rot(const Mat44f& 矩阵) {
	mat3X3 mat;
	mat.row0 = { 矩阵.m00, 矩阵.m01, 矩阵.m02 };
	mat.row1 = { 矩阵.m10, 矩阵.m11, 矩阵.m12 };
	mat.row2 = { 矩阵.m20, 矩阵.m21, 矩阵.m22 };

	vec3 rot = f_graph_旋转矩阵转欧拉角(mat);

	return f_mat44_to_33(f_mat44_构建欧拉角旋转矩阵(rot));
}*/
Inline Mat44f f_mat44_3x3(const Mat44f& 矩阵) {
	Mat44f mat = 矩阵;
	mat.m30 = 0;
	mat.m31 = 0;
	mat.m32 = 0;
	return mat;
}






Inline Mat44f f_mat4_右手转左手坐标系(Mat44f mat) {
	return f_mat44_构建X旋转矩阵(-90) * f_mat4_构建缩放矩阵({ 1,-1,1 }) * mat;
}

Inline Mat44f f_mat4_创建左手转右手坐标系() {
	return f_mat4_构建缩放矩阵({ 1, -1, 1 }) * f_mat44_构建X旋转矩阵(90) ;
}
Inline Mat44f f_mat4_左手转右手坐标系(const Mat44f& mat) {
	return f_mat44_构建X旋转矩阵(90) * f_mat4_构建缩放矩阵({ 1, 1, -1 }) * mat;
	//return f_mat4_构建缩放矩阵({ 1, 1, -1 }) * f_mat44_构建X旋转矩阵(90) * mat;
}







